package ca.etsmtl.gti785.util;

import java.util.Observable;
import java.util.Observer;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;

/**
 * This class is used to keep tracks of the GPS in the mobile device.
 * Source: http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial/
 * @author Étienne Faucher
 */
public class GPSTracker extends Service implements LocationListener {
	private final Context _context;
	private final Observable _observable;
	
    private boolean _isGPSEnabled = false;
    private boolean _isNetworkEnabled = false;
    private boolean _canGetLocation = false;

    // The minimum distance to change Updates in meters
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
 
    // The minimum time between updates in milliseconds
    private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
 
    protected LocationManager _locationManager;
 
    private Location _location; 
    private double _latitude; 
    private double _longitude; 

    public double getLatitude()
    {
        if(_location != null)
        {
            _latitude = _location.getLatitude();
        }
         
        return _latitude;
    }
     
    public double getLongitude()
    {
        if(_location != null)
        {
            _longitude = _location.getLongitude();
        }
        
        return _longitude;
    }
    
    public boolean canGetLocation() {
        return _canGetLocation;
    }
    
    public GPSTracker(Context context)
    {
    	_context = context;
    	_observable = new Observable();
        getLocation();
    }
    
    
    public Location getLocation() 
    {
        try 
        {
            _locationManager = (LocationManager) _context.getSystemService(LOCATION_SERVICE);
 
            // getting GPS status
            _isGPSEnabled = _locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
 
            // getting network status
            _isNetworkEnabled = _locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
 
            if (_isGPSEnabled && _isNetworkEnabled) 
            {
            	_canGetLocation = true;
                // First get location from Network Provider
                if (_isNetworkEnabled) 
                {
                    _locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    
                    if (_locationManager != null) 
                    {
                        _location = _locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (_location != null) 
                        {
                            _latitude = _location.getLatitude();
                            _longitude = _location.getLongitude();
                        }
                    }
                }
                // if GPS Enabled get lat/long using GPS Services
                if (_isGPSEnabled) 
                {
                    if (_location == null) 
                    {
                        _locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        if (_locationManager != null) 
                        {
                            _location = _locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (_location != null) 
                            {
                                _latitude = _location.getLatitude();
                                _longitude = _location.getLongitude();
                            }
                        }
                    }
                }
            }
            else
            {
            	showSettingsAlert();
            }
 
        } catch (Exception e) 
        {
            e.printStackTrace();
        }
 
        return _location;
    }
    
     
    public void showSettingsAlert(){
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(_context);
      
        // Setting Dialog Title
        alertDialog.setTitle("GPS is settings");
  
        // Setting Dialog Message
        alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
  
        // On pressing Settings button
        alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() 
        {
            public void onClick(DialogInterface dialog,int which) 
            {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                _context.startActivity(intent);
            }
        });
  
        // on pressing cancel button
        alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() 
        {
            public void onClick(DialogInterface dialog, int which) 
            {
            	dialog.cancel();
            }
        });
  
        // Showing Alert Message
        alertDialog.show();
    }
    
    public void addObserver(Observer obs)
    {
    	_observable.addObserver(obs);
    }
	
	@Override
	public void onLocationChanged(Location location) 
	{
		_location = location;
		_observable.notifyObservers();
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) 
	{
		// TODO Not Implemented.

	}

	@Override
	public void onProviderEnabled(String provider) 
	{
		// TODO Not Implemented.

	}

	@Override
	public void onProviderDisabled(String provider) {
		// TODO Not Implemented.

	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Not Implemented.
		return null;
	}

}
